#title: 本地化字符串
#index:0,1
#author: zozoh(zozohtnt@gmail.com)
------------------------------------------------------------------------------------------
基本策略
	每个 Mvc 框架都有自己的本地化字符串的解决方案， Nutz.Mvc 的这个是相当简陋的。
	我只是个人觉得足够用了。下面我把它简单介绍一下：
	
	 * 假定所有的本地化字符串文件都会存放在某一目录下
		 * 这个目录下所有的 .properties 文件，将作为默认的本地字符串文件。
		 * 每一种语言都会是一个目录，目录名称对应一个 Locale 的 toString()，请参看 java.util.Locale 的 JDoc
			 * 比如简体中文，就是 zh_CN
			 * 比如美式英语，就是 en_US
		 * 目录下所有的 .properties 文件存放着该地区的字符串信息
		 *  .properties 文件需要按照 UTF-8 方式编码
	 * 目录，通过 @Localization("全路径") 声明在主模块上
	 * 当应用启动时，一次读入所有的字符串，并存入 ServletContext，属性名称为：“org.nutz.mvc.annotation.Localization”
	 * 应用可以自行设置当前 Session 是哪一个国家和地区
		 * Mvcs.setLocaleName(String localeName)
	 * 每次请求时，会根据 Session 中的 localeName，从 ServletContext 中将对应 Locale 的字符串取出，设入 Request 对象
		 * 属性名为 "msg"
		 * 如果当前会话没有被设置 Locale，则将 "msg" 设置成默认本地化字符串
------------------------------------------------------------------------------------------
使用字符串
	在主模块上声明
		比如：
		{{{
		...
		@Localization("mymsg")
		public class MyMainModule {
			...
		}}}
		 * 在主模块上声明 `@Localization` 注解，指向一个目录
		 * 在目录下建立文件夹，比如 {*zh_CN}，每个目录下所有 {* .properties} 文件都会被当作字符串文件
		 * {* .properties} 文件 一定要是 UTF-8 编码的
		 * 比如 `@Locallization("mymsg")` 会指向 CLASSPATH 下的 {*mymsg} 目录
	
	在 JSP 里使用
		{*直接 Scriptlet}
		{{{
		...
		<h1><%=((Map<String,String>)request.getAttribute("msg")).get("my.msg.key")%></h1>
		...
		}}}
		
		{*采用 JSTL}
		{{{
		...
		<h1>${msg['my.msg.key']}</h1>
		...
		}}}
		 
	我到底支持哪些语言
		
		请参看 {*org.nutz.mvc.Mvcs} 的 JavaDoc，这里我列几个常用的方法:
		
		|| Mvcs.getLocalizationKey()                || 获取当前会话的 Locale 名称 ||
		|| Mvcs.setLocalizationKey(String key)      || 为当前会话设置 Locale 的名称 ||
		|| Mvcs.getLocalizationKeySet()             || 获取整个应用可用的 Locale 名称集合 ||
		
------------------------------------------------------------------------------------------
切换本地语言
    
    自从 1.b.44 之后，Nutz 对本地字符串语言切换的接口做了改动:

    {{{
    // 设置一个本地字符串
    @At("/lang/change")
    @Ok("redirect:/")
    public void changeLocal( @Param("lang") String lang){
        Mvcs.setLocalizationKey(lang);
    }
    }}}

    1.b.44 版本 之前，只能采用如下方法:
    {{{
    // 设置一个本地字符串
    @At("/lang/change")
    @Ok("redirect:/")
    public void changeLocal( @Param("lang") String lang, HttpSession sess){
        Mvcs.setLocale(sess, lang);
        Mvcs.setLocaleName(sess, lang);
    }
    }}}

------------------------------------------------------------------------------------------
设置应用程序的默认语言
    
    对于任何一个支持多语言版本的应用程序，第一次启动的时候，总要采用一种语言。
    自 1.b.44 之后，Nutz 给出了一个明确的方法，来设置这个信息。你可以在应用程序启动的
    Setup 时，调用:
    {{{
    ...
    Mvcs.setDefaultLocalizationKey("zh_CN");
    ...
    }}}

    在 1.b.45 后，Nutz 又给出一个更直接的实现，你可以直接:
    {{{
    ...
    @Localization(value="mymsg", defaultLocalizationKey="zh_CN")
    public class MyMainModule {
    ...
    }}}

------------------------------------------------------------------------------------------
使用过滤器
	有些是由，你想让你的 JSP 文件 (不是通过 Nutz.Mvc 入口函数访问的)也可以使用"{*本地化字符串}"
	功能，那么你需要在 web.xml 这么配置:
	{{{
	<!--
		Nutz.Mvc 还提供了一个过滤器，你可以用这个过滤器为所有的直接访问的 jsp 设置必要的 Request 属性。 比如 ${base}
		以及 ${msg}
	-->
	<filter>
		<filter-name>msgs</filter-name>
		<filter-class>org.nutz.mvc.NutFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>msgs</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>msgs</filter-name>
		<url-pattern>*.jspx</url-pattern>
	</filter-mapping>
	}}}
	
------------------------------------------------------------------------------------------
定制自己的本地化字符串方式
    
    你需要自己实现一个 MessageLoader 的接口，然后声明到 '@Localization' 中。
    比如你的实现类名字为 'MyMessageLoader'，那么你应该这么声明:
    {{{
    ...
    @Localization( type=MyMessageLoader.class,
                   value="msg" )
    public class MyMainModule {
    ...
    }}}

    对于 MessageLoader 接口，就一个方法需要你来实现:
    {{{
    public interface MessageLoader {
        /**
         * 本函数将根据传入的 "refer" 参数，返回一个 Map <br>
         * Map 的键是语言的名称，比如 "en_US", "zh_CN" 等，<br>
         * 你会通过 Mvcs.setLocalizationKey 来直接使用这个键值
         * <p>
         * 与键对应的是一个消息字符串的 Map, 该 Map 的键就是消息键，值就是消息内容
         * 
         * @param refer
         *            参考值。来自 '@Localization.value'
         * @return 多国语言字符串的 Map
         */
        Map<String, Map<String, Object>> load(String refer);
    }
    }}}

    你声明在 '@Localization' 中的 "value" 的值，会被传入这个接口，作为 refer 参数的值

------------------------------------------------------------------------------------------
让 Ioc 容器管理你的 MessageLoader
    
    这是 1.b.45 已后才有的方法:
    {{{
    ...
    @Localization( type=MyMessageLoader.class,
                   beanName="myMessages", 
                   value="msg" )
    public class MyMainModule {
    ...
    }}}

    提供了 "beanName" 属性，这样，Nutz.Mvc 将从 Ioc 容器中加载名字为 "myMessages" 的对象。
    当然它的类型必须是你声明的 "MyMessageLoader.class" 



















